<template>
  <div>
    <pre-zjcl class="prezjcl" :inline="false" ref="PreZjcl"></pre-zjcl>

    <c-k-editor style="height: 100%" ref="CKEditor"
                @refresh="refresh"
                @save="saveDoc"
                @paste="paste"
                @drop="editorDrop"
                @loaded="setDocEditorData"
                @insertCatalog="insertCatalog"
    ></c-k-editor>
  </div>
</template>

<script>
import {mapState} from 'vuex'

import SQLite from '../common/SQLiteHelper'
import evidenceCatalogTree from '../config/evidenceCatalogTree'
import preplanServer from '../server/preplan/preplanServer'

let remote = ''
let BrowserWindow = ''

const {
  CMD: {openDirOrFile},
  util: {textToImg, insertAfter}
} = require('../util')

export default {
  name: 'DocView',
  data() {
    return {
      isEdited: false,
      evidenceCatalogTreeData: []
    }
  },
  computed: {
    ...mapState({
      retrieveDataSource: state => state.appearCourt.retrieveDataSource,
      // isPlay: state => state.slideEditor.isPlay,
      casePath: state => state.appearCourt.casePath,
      isAddZjcl: state => state.common.preplanOptions.isAddZjcl,
      isAddWjnr: state => state.common.preplanOptions.isAddWjnr,
      caseInfo: state => state.appearCourt.caseInfo,
      // evidenceCatalogTreeData: state => state.preplan.evidenceCatalogTreeData,
      tempData: state => state.common.tempData
    }),
    innerDocument() {
      return this.$refs.CKEditor.editor.document.$
    }
  },
  methods: {
    getData() {
      return this.$refs.CKEditor.editor.getData()
    },
    /**
     * 导出为Word文档
     */
    async HtmlToWord() {
      try {
        let win = BrowserWindow.getFocusedWindow()
        let res = remote.dialog.showSaveDialog(win, {
          title: '导出word',
          defaultPath: this.caseInfo.AJMC || 'test.doc',
          filters: [{
            name: 'Word',
            extensions: ['doc']
          }]
        })
        if (!res) return
        this.loadStatus({loading: true, loadingText: '导出中'})
        let html = this.getData()

        let div = document.createElement('div')
        div.innerHTML = html
        let els = div.querySelectorAll('*[nodeID]')

        let datasource = []
        if (this.isAddWjnr) {
          let arr = []
          els.forEach(item => {
            arr.push(item.getAttribute('fileID'))
          })

          datasource = await preplanServer.getEvidenceMaterialText(arr)
        }

        for (let i = 0; i < els.length; i++) {
          let el = els[i]
          let alt = el.alt
          let nodeID = el.getAttribute('nodeID')
          let fileID = el.getAttribute('fileID')
          let span = el
          if (alt) {
            span = document.createElement('span')

            span.style.display = 'inline-block'
            span.style.color = 'blue'
            span.style.fontSize = '14pt'
            span.style.cursor = 'pointer'
            span.style.textDecoration = 'underline'

            span.className = 'MsoHyperlink'
            span.innerText = alt
            span.title = alt

            span.setAttribute('nodeID', nodeID)
            span.setAttribute('fileID', fileID)

            el.parentElement.insertBefore(span, el)
            el.parentElement.removeChild(el)
          }

          if (!this.isAddWjnr) continue
          let nodeText = ''
          datasource.filter(item => item.WJID === fileID).forEach(item => {
            nodeText += item.TEXT
          })
          if (!nodeText) continue

          let spanText = document.createElement('span')
          spanText.style.fontSize = '14pt'
          spanText.innerText = `【${nodeText}】`
          insertAfter(span, spanText)
        }
        html = div.innerHTML
        html = html.replace(/<title><\/title>/ig, '')

        html = `<!DOCTYPE html>
                    <html lang="en">
                      <head>
                        <meta charset="UTF-8">
                        <meta http-equiv="content-type" content="application/msword;charset=utf-8">
                      </head>
                      <body style="font-family: 仿宋;font-size: 12pt">
                        ${html}
                      </body>
                    </html>`

        let result = await SQLite.HtmlExportWord({
          html: Buffer.from(html, 'UTF-8'),
          filePath: res
        })

        if (result) {
          try {
            await this.$confirm('导出成功，是否打开？', '提示')
            openDirOrFile(res)
          } catch (e) {
            console.log(e)
          }
        } else {
          this.$message({
            message: '导出失败，失败原因：' + result,
            type: 'error'
          })
        }
      } catch (e) {
        this.$message({
          message: '导出失败，失败原因：' + e.message,
          type: 'error'
        })
      } finally {
        this.loadStatus({loading: false})
      }
    },
    refresh() {
      this.bindEvent()
      this.setStyle()
    },
    getInsertElement(data) {
      // let outSpan = document.createElement('span');
      // let inSpan = document.createElement('span');
      //
      // inSpan.style.display = 'inline-block';
      // inSpan.style.color = 'blue';
      // inSpan.style.fontSize = '14pt';
      // inSpan.style.cursor = 'pointer';
      // inSpan.style.textDecoration = 'underline';
      //
      // inSpan.className = 'MsoHyperlink';
      // inSpan.innerText = data.MLXSMC || data.alias;
      // inSpan.title = data.MLXSMC || data.alias;
      //
      // inSpan.setAttribute('nodeID', data.id);
      // inSpan.setAttribute('fileID', data.fileID);

      let img = new Image()
      img.className = 'MsoHyperlink'
      img.title = data.MLXSMC || data.alias
      img.src = textToImg(data.MLXSMC || data.alias, {color: 'blue', fontSize: '19px', font: '仿宋'})
      img.alt = data.MLXSMC || data.alias
      img.setAttribute('nodeID', data.id)
      img.setAttribute('fileID', data.fileID)
      img.style.verticalAlign = 'text-bottom'
      img.style.paddingLeft = '3px'
      img.style.paddingRight = '3px'

      // outSpan.appendChild(img);
      // outSpan.appendChild(inSpan);

      return img
    },
    insertIntoDoc(nodes) {
      for (let data of nodes) {
        let outSpan = this.getInsertElement(data)
        this.insertHtml(outSpan.outerHTML)
      }
    },
    /**
     * 插入示证目录
     */
    insertCatalog() {
      this.evidenceCatalogTreeData = evidenceCatalogTree.state.evidenceCatalogTreeData
      let catalogML = JSON.parse(JSON.stringify(this.evidenceCatalogTreeData))
      let p = this.recursionTreeData(catalogML)
      if (!this.getData()) {
        this.$refs.CKEditor.setData(p.innerHTML)
      } else {
        this.insertHtml(p.innerHTML)
      }
    },
    /**
     * 递归树
     */
    recursionTreeData(arr, el = document.createElement('p'), no = '') {
      let index = -1
      arr.forEach((obj) => {
        let _el = document.createElement('p')

        if (Number(obj.type) === 0) {
          if (obj.pid === '-1') {
            _el.style.textAlign = 'center'
            _el.innerHTML = `<strong><span style="font-size: 24pt">${obj.alias}</span></strong>`
          } else {
            index++
            if (!no) {
              _el.innerHTML = `<strong><span style="font-size: 18pt">${no}${index + 1} ${obj.alias}</span></strong>`
            } else {
              _el.innerHTML = `<span style="font-size: 16pt">${no}${index + 1} ${obj.alias}</span>`
            }
          }
          _el.style.fontSize = '18pt'
          _el.style['-webkit-margin-after'] = '10px'
          _el.style['-webkit-margin-before'] = '10px'

          _el.id = obj.id + 'catalog'
          // _el.setAttribute('contenteditable', false);
          obj.fileID && _el.setAttribute('fileID', obj.fileID)
          el.appendChild(_el)
          if (obj.pid !== '-1' && obj.comment) {
            let temp = document.createElement('p')
            temp.style.paddingLeft = '20pt'
            temp.style.fontSize = '14pt'
            temp.innerHTML = obj.comment
            el.appendChild(temp)
          }
        }
        if (Number(obj.type) !== 0) {
          if (this.isAddZjcl) {
            let __el = document.createElement('p')
            __el.style.paddingLeft = '20pt'
            __el.appendChild(this.getInsertElement(obj))
            el.appendChild(__el)
          } else {
            return
          }// 跳过文件 strong
        }
        let _no = obj.pid === '-1' ? '' : `${no}${index + 1}.`
        obj.children && this.recursionTreeData(obj.children, el, _no)
      })
      return el
    },
    /**
     * 滚动到视图中
     * @param flag id/className
     * @param isId
     */
    scrollIntoView(flag, isId = true) {
      let el = this.innerDocument[isId ? 'getElementById' : 'getElementByClass'](flag)
      el && el.scrollIntoView({behavior: 'smooth', block: 'nearest', inline: 'nearest'})
    },
    paste(ev) {
      ev.stop()
      ev.cancel()
      console.log(ev)
      this.insertHtml(ev.data.dataValue)
      // this.editor.document.$.execCommand("paste");
    },
    editorDrop(ev) {
      let range = ''
      let type = ''
      if (!ev.data) {
        if (ev.pointerType === 'touch') return
        if (ev.button !== 0) return
        type = this.tempData.type
        if (!type) return

        range = this.innerDocument.caretRangeFromPoint(ev.clientX, ev.clientY)
      } else {
        ev.stop()
        ev.cancel()
        let el = ev.data.$
        range = this.innerDocument.caretRangeFromPoint(el.clientX, el.clientY)
      }

      // 文书卷宗和电子卷宗
      if (type === 'juanzong' || type === 'evidence') {
        // let contents = JSON.parse(ev.data.dataTransfer.getData('text/plain'));
        let contents = JSON.parse(this.tempData.data)
        for (let content of contents) {
          if (Number(content.type) === 0) continue
          let outSpan = this.getInsertElement(content)
          range.insertNode(outSpan)
          range.setStartAfter(outSpan)
        }
      } else {
        let dt = ev.data.$.dataTransfer
        let html = dt.getData('text/html')
        let plain = dt.getData('text/plain')
        let files = dt.files
        this.innerDocument.getSelection().getRangeAt(0).deleteContents()
        if (html) {
          let span = document.createElement('span')
          span.innerHTML = html
          range.insertNode(span)
          range.setStartAfter(span)
        } else if (plain) {
          let span = document.createElement('span')
          span.innerText = plain
          range.insertNode(span)
          range.setStartAfter(span)
        } else {
          let span = document.createElement('span')
          for (let file of files) {
            let _span = document.createElement('span')
            _span.innerText = file.name
            _span.title = file.path
            span.appendChild(_span)
          }
          range.insertNode(span)
          range.setStartAfter(span)
        }
      }
      this.$emit('drop-end', type)
      this.$nextTick(() => {
        this.bindEvent()
      })
      this.isEdited = true
      this.$refs.CKEditor.editor.focus()
    },
    async saveDoc(html, isShowDialog) {
      if (!this.isEdited) return
      // doctext
      let result = null
      result = await SQLite.ExecuteNonQuery({
        executeSql: [
          {
            SQL: 'replace INTO doctext (id,doctext) VALUES(@id,@doctext)',
            Parameter: {id: 1, doctext: html}
          }]
      })

      if (result) {
        isShowDialog && this.$alert('保存成功！', '提示', {type: 'success'})
        this.isEdited = false
        console.log('保存成功')
      } else {
        this.$alert('保存失败！', '错误', {type: 'error'})
      }
    },

    async setDocEditorData() {
      this.$refs.CKEditor.editor.on('change', ev => {
        this.isEdited = true
      })

      this.$refs.CKEditor.editor.addCommand('preview', {
        // editorFocus: false,
        exec: (editor, a, b, c) => {
          console.log(editor, a, b, c)
          console.log(editor.selection)
          console.log('预览')
        }
      })
      this.$refs.CKEditor.editor.addCommand('project', {
        // editorFocus: false,
        exec: editor => {
          console.log('投影')
        }
      })
      this.$refs.CKEditor.editor.addCommand('clearAllContent', {
        // editorFocus: false,
        exec: async editor => {
          try {
            await this.$confirm('是否清空预案编辑器内容？')
            console.log('清除所有内容')
            this.$refs.CKEditor.setData('')
            // editor.execCommand("undo")
          } catch (e) {
            console.error(e)
          }
        }
      })
      this.$refs.CKEditor.editor.addCommand('clearlink', {
        // editorFocus: false,
        exec: editor => {
          let el = editor.getSelection().getStartElement().$
          let isLink = el.classList.contains('MsoHyperlink')
          if (!isLink) return
          let text = el.alt
          if (!text) {
            el.classList.remove('MsoHyperlink')
            el.removeAttribute('nodeID')
            el.style.color = '#000'
            el.style.cursor = 'auto'
            el.style.textDecoration = 'none'
            el.onclick = null
          } else {
            let span = document.createElement('span')

            span.style.display = 'inline-block'
            span.style.color = '#000'
            span.style.fontSize = '14pt'
            span.style.cursor = 'auto'
            span.style.textDecoration = 'none'

            span.innerText = text

            el.parentElement.insertBefore(span, el)
            el.parentElement.removeChild(el)
          }
          this.bindEvent()
        }
      })
      this.$refs.CKEditor.editor.addCommand('slideshow', {
        // editorFocus: false,
        exec: editor => {
          console.log('播放幻灯片')
        }
      })

      this.$refs.CKEditor.editor.addCommand('exporttoword', {
        exec: editor => {
          this.HtmlToWord()
        }
      })
      let res = (await SQLite.ExecuteReader({
        SQL: 'select * from doctext',
        Parameter: {}
      }))[0]
      let html = res ? res.doctext : ''
      if (!html) {
        this.insertCatalog()
      } else {
        this.$refs.CKEditor.setData(html)
      }
    },
    insertElement(elementName, text, styles, attributes, eventListeners) {
      this.$refs.CKEditor.insertElement(elementName, text, styles, attributes, eventListeners)
      this.bindEvent()
    },
    insertHtml(html) {
      this.$refs.CKEditor.insertHtml(html)
      this.bindEvent()
    },
    bindEvent() {
      console.log('绑定事件')
      this.$nextTick(() => {
        this.innerDocument.onpointerup = this.editorDrop
        let els = this.innerDocument.querySelectorAll('*[nodeID]')
        for (let i = 0; i < els.length; i++) {
          let el = els[i]
          let nodeID = el.getAttribute('nodeID')
          let node = this.$parent.$parent.$refs.evidenceCatalogTree.getNode(nodeID)
          if (node) {
            el.onclick = ev => {
              if (!nodeID) return
              this.setStyle(nodeID)
              this.$emit('zjcl-click', nodeID)
              this.innerDocument.getSelection().removeAllRanges()
            }
            // el.ondragstart = ev => {
            //   ev.preventDefault();
            // }
          } else {
            el.parentElement.removeChild(el)
          }
        }
      })
    },
    setStyle(nodeID = '') {
      let els = this.innerDocument.querySelectorAll('*[nodeID]')
      let isScrolled = false
      for (let i = 0; i < els.length; i++) {
        let el = els[i]
        let _nodeID = el.getAttribute('nodeID')
        let text = el.alt

        let src = ''
        if (_nodeID === nodeID) {
          if (!isScrolled) {
            console.log('预案滚动')

            let start = this.innerDocument.scrollingElement.scrollTop
            let end = start + this.innerDocument.scrollingElement.clientHeight

            if (!(el.offsetTop > start && el.offsetTop < end)) this.innerDocument.scrollingElement.scrollTop = el.offsetTop

            el.scrollIntoView({behavior: 'smooth', block: 'nearest', inline: 'nearest'})
            isScrolled = true
          }

          if (!text) {
            el.style.background = 'blue'
            el.style.color = 'white'
            continue
          }
          src = textToImg(text, {color: 'white', fontSize: '19px', font: '仿宋', background: 'blue'})
        } else {
          if (!text) {
            el.style.background = 'transparent'
            el.style.color = 'blue'

            continue
          }
          if (text) src = textToImg(text, {color: 'blue', fontSize: '19px', font: '仿宋', background: 'transparent'})
        }
        el.src = src
      }
    }
  }
}
</script>

<style scoped>
.prezjcl {
  z-index: 100;
}
</style>
